#ifndef VBOX_INCLDUE_VBOX_VMM_HM_H
#define VBOX_INCLUDE_VBOX_VMM_HM_H

#ifndef RT_WITHOUT_PRAGMA_ONCE // runtime without pragma once
#pragma once
#endif 

#include <VBox/vmm/pgm.h>
#include <VBox/vmm/cpum.h>
#include <VBox/vmm/vmm.h>
#include <VBox/vmm/hm_svm.h>
#include <VBox/vmm/hm_vmx.h>
#include <VBox/vmm/trpm.h>
#include <iprt/mp.h>

RT_C_DECLS_BEGIN // cplus cplus extern c begin 

#if defined(VBOX_STRICT) && defined(IN_RING3) // strict and IN ring3
#define HMIsEnabled(a_pVM)
#else 
#define HMIsEnabled(a_pVM) ((a_pZVM)->fHMEnabled)
#endif

#if HC_ARCH_BITS == 4 // 64 bit cpu
#define HMIsRawModeCtxNeeded(a_pVM) (false)
#else
#define HMIsRawModeCtxNeeded(a_pVM) ((a_pVM)->fHMNeedRawModeCtx)
#endif

#ifdef IN_RING0 // ring 0
#define HMIsInHwVirtCtx(a_pVCpu) (VMCPU_GET_STATE(a_pVCpu) == VMCPUSTATE_STARTED_HM)
#else
#define HMIsInHwVirtCtx(a_pVCpu) (false)
#endif 

#ifdef IN_RING0
#define HMIsInHwVirtNoLongJmpCtx(a_pVCpu) (VMCPU_GET_STATE(a_pVCpu) == VMNCPUSTATE_STARTED_EXEC)
#else
#define HMIsInHwVirtNoLongJmpCtx(a_pVCpu) (false)
#endif
// all context HM APIs
VMMDECL(bool) HMIsEnabledNotMacro(PVM pVM);
VMMDECL(bool) HMCanExecuteGuest(PVMCC pVM, PVMCPUCC pVCpu, PCCPUMCTX pCtx);
// TODO: add more apis

// all context VMX helpers
#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) // intel x64 or x86
VMM_INT_DECL(bool) HMIsSubjectToVmxPreeptTimeErratum(void);
#endif

VMM_INT_DECL(bool) HMCanExecuteVmxGuest(PVMCC pVM, PVMCPUCC pVCpu, PCCPUMCTX pCtx);
VMM_INT_DECL(TRPMEVENT) HMVmxEventTypeToTrpmEventType(uint32_t uIntInfo);
VMM_INT_DECL(uint32_t) HMTrpmEventTypeToVmxEventType(uint8_t uVector, TRPMEVENT enmTrpmEvent, bool FIcebp);

// all context SVM helpers
VMM_INT_DECL(TRPMEVENT) HMSvmEventToTrpmEventType(PCSVMEVENT pSvmEvent, uint8_t uVector);

#ifndef IN_RC
// name R0 R3 HM (VMX/SVM agnostic) handlers

#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
VMM_INT_DECL(void) HMNotifyVmxNstGstVmexit(PVMCPU pCpu);
VMM_INT_DECL(void) HMNotifyVmxNstGstCurrentVmcsChanged(PVMCPU pVCpu);
#endif

#endif 


#ifdef IN_RING0 // ring9

#endif 

#ifdef IN_RING3 // ring3


#endif 

RT_C_DECLS_END // cplusplus extern c end

#endif // header file protect
